// 业务plugin 加入监控模块
const HtmlWebpackPlugin = require("html-webpack-plugin");
const cheerio = require("cheerio");
const UglifyJS = require("uglify-js");
const paths = require("../config/paths");
const logTag = require(paths.appPackageJson).logTag;

const windowerror =
  "<script>" +
  UglifyJS.minify(`
    window.addEventListener('error', function (e) {
      e.stopImmediatePropagation();
      var srcElement = e.srcElement;
      var data = {};
      if (srcElement === window) {
        data.kind = '【window.onerror js】'
        data.msg = {
          msg: e.message,
          err: e.error && e.error.stack,
          line: e.lineno,
          col: e.colno
        }
      } else {
        // 资源请求失败 暂时移除 没有记录价值
        data.kind = '【window.onerror resource】'
        data.msg = {
          tagName: srcElement.tagName,
          res: srcElement.href || srcElement.src
        }
        return
      }
      monitorlog(data)
    }, true);

    function monitorlog(data) {
      data.url = location.href
      data.userAgent = navigator.userAgent
      data.uinfo = getCookieUid('TOKEN') || ''
      var img = new Image;
      img.onload = img.onerror = function () {
        img = null;
      };
      if (/local./.test(location.host)) {
        console.error('监控：', data)
      } else {
        img.src = getMoniterHost() + '/docsserver/public/monitor/log?msg=' + encodeURIComponent('${logTag}') + '__' + encodeURIComponent(JSON.stringify(data))
      }
    }

    function getMoniterHost() {
      var envs = /([a-z]+).([a-z]+).com/.exec(location.host)
      var host = ''
      if (envs && envs[1]) {
      }
      return host
    }

    function getCookieUid(name) {
      var value = "; " + document.cookie;
      var parts = value.split("; " + name + "=");
      if (parts.length == 2) {
        var token = parts.pop().split(";").shift();
        return token
      }
    }
`).code +
  "</script>";

const vueerror =
  "<script>" +
  UglifyJS.minify(`
    if (window.Vue) {
      window.Vue.config.errorHandler = function (err, vm, info) {
        var data = {
          kind: '【window.Vue.config.errorHandler】',
          vue: {
            err: err.stack,
            tag: vm.$vnode && vm.$vnode.tag,
            tagName: vm.$el && vm.$el.tagName,
            className: vm.$el && vm.$el.className
          }
        }
        monitorlog(data)
  
        console.error(err, vm, info);
      }
    }
`).code +
  "</script>";

class Monitor {
  apply(compiler) {
    compiler.hooks.compilation.tap("Monitor", compilation => {
      // Static Plugin interface |compilation |HOOK NAME | register listener
      HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(
        "Monitor", // <-- Set a meaningful name here for stacktraces
        (data, cb) => {
          // Manipulate the content
          const $ = cheerio.load(data.html);
          $("head title").after(windowerror);
          $("body").append(vueerror);
          data.html = $.html();
          // Tell webpack to move on
          cb(null, data);
        }
      );
    });
  }
}

module.exports = Monitor;
